package com.zhang.buiness.amaster.workserver.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.zhang.buiness.amaster.workserver.client.fegin.ConfigEnvServiceClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import java.util.Arrays;
import java.util.List;

@Service
public class WorkServiceImpl {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WorkServiceImpl.class);



    @Value("${word}")
    private String word;

    @Autowired
    private ConfigEnvServiceClient configEnvServiceClient;

    public List<String> getWorkEnvConfig() {
        return Arrays.asList(word);
    }


    /**
     * 通过opeFegin 测试请求接口+hystrix的降级测试
     * @return
     */
    public List<String> getConfigEnvConfig() {
       return configEnvServiceClient.getEnvConfig();
    }

    /**
     *
     * 熔断降级测试
     * hystrixCircuitBreakHystrix  熔断降级测试
     * 通过opeFegin 测试请求接口+hystrix的降级测试
     * @return
     */
    @HystrixCommand(fallbackMethod = "circuitBreakHystrixFallback",groupKey = "breakHystrixTest",commandKey = "getcircuitBreakHystrixTest", commandProperties = {
            @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED, value = "true"),// 是否开启熔断器
            @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "20"),      // 统计时间窗内请求次数
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),// 在统计时间窗内，失败率达到50%进入熔断状态
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000"), // 休眠时间窗口
            @HystrixProperty(name = HystrixPropertiesManager.METRICS_ROLLING_STATS_TIME_IN_MILLISECONDS, value = "10000") // 统计时间窗
    })
    public List<String> getcircuitBreakHystrixTest() {
        return configEnvServiceClient.getcircuitBreakHystrixTest();
    }

    public List<String> circuitBreakHystrixFallback() {
        return Arrays.asList("Fallback response  circuitBreakHystrixFallback");
    }


    /**
     * 超时降级测试
     * @return
     */
    @HystrixCommand(fallbackMethod = "TimeoutBreakHystrixFallback",groupKey = "breakHystrixTest",commandKey = "getTimeoutBreakHystrixTest", commandProperties = {
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = "true"),
            // 是否开启超时降级
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "5000"),
            // 请求的超时时间，默认10000
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_INTERRUPT_ON_TIMEOUT, value = "true")
            // 当请求超时时，是否中断线程，默认true
    })
    public List<String> getTimeoutBreakHystrixTest() {
        try {
            log.info("getTimeoutBreakHystrixTest start");
            Thread.sleep(7000);
            log.info("getTimeoutBreakHystrixTest end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return configEnvServiceClient.getBreakHystrixTest();
    }


    public List<String> timeoutBreakHystrixFallback() {
        return Arrays.asList("Fallback response  timeoutBreakHystrixFallback");
    }


    /**
     * 资源隔离触发降级
     * @return
     */
    @HystrixCommand(fallbackMethod = "threadIsolationFallback",groupKey = "breakHystrixTest",commandKey = "getExecutionIsolation_strategyHystrixTest",commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "THREAD")
            },
            threadPoolProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "1"),
                    @HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE, value = "-1"),
                    @HystrixProperty(name = HystrixPropertiesManager.QUEUE_SIZE_REJECTION_THRESHOLD, value = "1"),
                    @HystrixProperty(name = HystrixPropertiesManager.KEEP_ALIVE_TIME_MINUTES, value = "1"),
            }
    )
    public List<String> getExecutionThreadIsolation_strategyHystrixTest() {
        try {
            log.info("getExecutionThreadIsolation_strategyHystrixTest start");
            Thread.sleep(10000);
            log.info("getExecutionThreadIsolation_strategyHystrixTest end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.error("begin log");
     // return Arrays.asList("success response  isolationFallbackFallback");
        return configEnvServiceClient.getBreakHystrixTest();
    }

    public List<String> threadIsolationFallback() {
        log.error("FallbackFallback log");
        return Arrays.asList("Fallback response  threadIsolationFallback");
    }


    /**
     * 信号量资源隔触发降级降级
      */
    @HystrixCommand(fallbackMethod = "semaphoreisolationFallback",
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),
                    @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "2")
            }
    )
    public List<String> getSemaphoreIsolation_strategyHystrixTest() {
        try {
            log.info("getSemaphoreIsolation_strategyHystrixTest start");
            Thread.sleep(10000);
            log.info("getSemaphoreIsolation_strategyHystrixTest end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.error("begin log");
        //   return Arrays.asList("success response  isolationFallbackFallback");
        return configEnvServiceClient.getBreakHystrixTest();
    }

    public List<String> semaphoreisolationFallback() {
        log.error("FallbackFallback log");
        return Arrays.asList("Fallback response  threadIsolationFallback");
    }

}
